package com.rk.kbk.controller;

import com.rk.kbk.common.JsonResp;
import com.rk.kbk.dao.AddressDao;
import com.rk.kbk.dao.ContactsDao;
import com.rk.kbk.dao.UserDao;
import com.rk.kbk.dto.PageDto;
import com.rk.kbk.model.Address;
import com.rk.kbk.model.Contacts;
import com.rk.kbk.model.User;
import com.rk.kbk.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ContactsController
 * @通讯录Controller
 * @version : Ver 1.0
 */
@CrossOrigin
@RestController
@Transactional
@RequestMapping(value="/api/contacts")
public class ContactsController {
    private Logger log = Logger.getLogger(this.getClass());
    @Autowired
    private ContactsDao contactsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserService userService;
    @Autowired
    private AddressDao addressDao;
    @PersistenceContext
    private EntityManager entityManager;

    /**
     * @修改通讯录
     * @param contacts
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/updateContacts",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp updateContacts(@RequestBody Contacts contacts) {
        log.debug("修改通讯录");
        User shop=userDao.findOne(contacts.getShop().getId());
        Address address = contacts.getAddress();
        Address addressNew=addressDao.findOne(address.getId());
        addressNew.setLevel(0);//等级，默认0表示非默认地址，1表示默认地址
        addressNew.setRealName(address.getRealName());
        addressNew.setPhone(contacts.getPhone());
        addressNew.setSex(address.getSex());
        addressNew.setType(1);//用户地址
        addressNew.setStatus(1);
        addressNew.setAreaCode(address.getAreaCode());
        addressNew.setProvince(address.getProvince());
        addressNew.setCity(address.getCity());
        addressNew.setCounty(address.getCounty());
        addressNew.setLng(address.getLng());
        addressNew.setLat(address.getLat());
        addressNew.setAddressDetail(address.getAddressDetail());
        addressDao.save(addressNew);
        Contacts contacts1=contactsDao.findOne(contacts.getId());
        contacts1.setShop(shop);
        contacts1.setAddress(addressNew);
        contacts1.setPhone(contacts.getPhone());
        contactsDao.save(contacts1);
        return JsonResp.ok();
    }
    /**
     * @添加通讯录
     * @param contacts
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/addContacts",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp addContacts(@RequestBody Contacts contacts) {
        log.debug("添加通讯录");
        User shop=userDao.findOne(contacts.getShop().getId());
        List<Contacts> contactsList=contactsDao.findByShop(shop);
        Address address = contacts.getAddress();
        int i=0,y=contactsList.size();
        for(;i<y;i++){
            Contacts contacts1=contactsList.get(i);
            Address address1=contacts1.getAddress();
            address.setPhone(contacts.getPhone());
            if(address1.equals(address)){
                if(address1.getStatus()!=1){
                    address1.setStatus(1);
                    address.setType(1);//用户地址
                    addressDao.save(address);
                }
                break;
            }
        }
        if(i==y){//地址和通讯录中的地址都不一样  保存
            address.setLevel(0);//等级，默认0表示非默认地址，1表示默认地址
            address.setRealName(address.getRealName());
            address.setPhone(contacts.getPhone());
            address.setSex(address.getSex());
            address.setType(1);//用户地址
            address.setStatus(1);
            addressDao.save(address);
            contacts.setAddress(address);
            contacts.setShop(shop);
            contactsDao.save(contacts);
        }
        return JsonResp.ok();
    }

    /**
     * @批量添加/修改通讯录
     * @param contactss
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/addOrUpdateSomeContacts",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp addOrUpdateSomeContacts(@RequestBody List<Contacts> contactss){
        log.debug("批量添加/修改通讯录");
        contactsDao.save(contactss);
        return JsonResp.ok();
    }



    /**
     * @商家获取通讯录列表(新建订单用)
     *
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/findContactsList",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findContactsList(String phone,Long shopId){
        log.debug("商家获取通讯录列表");
        List<Contacts> contactsList=contactsDao.findByPhone(phone);
        List<Map> contactMapList=new ArrayList<>();
        for(int i=0,y=contactsList.size();i<y;i++){
            Map map=new HashMap();
            Contacts contacts=contactsList.get(i);
            User shop=contacts.getShop();
            User user=userDao.findOneByPhone(phone);
            Address address=contacts.getAddress();
            //如果该条通讯录属于该商家且电话一样    直接获取用户信息
            if(String.valueOf(shop.getId()).equals(String.valueOf(shopId))){
                    map.put("realName",address.getRealName());
                    map.put("phone",contacts.getPhone());
                    map.put("province",address.getProvince());
                    map.put("city",address.getCity());
                    map.put("county",address.getCounty());
                    map.put("addressId",address.getId());
                    map.put("addressDetail",address.getAddressDetail());
                    map.put("level",address.getLevel());//等级，默认0表示非默认地址，1表示默认地址
                    map.put("sex",address.getSex());
                    map.put("lng",address.getLng());
                    map.put("lat",address.getLat());
                    map.put("status",address.getStatus());
                    //如果一个用户对应的商家id不属于该商家则判断用户登录微信时间  少于20min也要显示在该商家通讯录中
                }else {
                    Date loginTime=user.getUptDatetime();
                    Long time=System.currentTimeMillis()-loginTime.getTime();//获取时间戳
                    if(time<120000){//时间戳小于两分钟
                        map.put("realName",address.getRealName());
                        map.put("phone",contacts.getPhone());
                        map.put("province",address.getProvince());
                        map.put("city",address.getCity());
                        map.put("county",address.getCounty());
                        map.put("addressDetail",address.getAddressDetail());
                        map.put("level",address.getLevel());//等级，默认0表示非默认地址，1表示默认地址
                        map.put("sex",address.getSex());
                        map.put("lng",address.getLng());
                        map.put("lat",address.getLat());
                        map.put("status",address.getStatus());
                    }
                }
            if(!map.isEmpty()){
                contactMapList.add(map);
            }
        }
        return JsonResp.ok(contactMapList);
    }



    /**
     * @商家获取通讯录列表
     *
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/findContactsListNoParameter",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findContactsListNoParameter(Long shopid) {
        log.debug("商家获取通讯录列表");
        User shop=userDao.findOne(shopid);
        List<Contacts> contactsList = contactsDao.findByShop(shop);
        List<Map> contactMapList = new ArrayList<>();
        for (int i = 0, y = contactsList.size(); i < y; i++) {
            Map map = new HashMap();
            Contacts contacts = contactsList.get(i);
            Address address = contacts.getAddress();
            map.put("realName", address.getRealName());
            map.put("phone", contacts.getPhone());
            map.put("province", address.getProvince());
            map.put("city", address.getCity());
            map.put("county", address.getCounty());
            map.put("addressDetail", address.getAddressDetail());
            map.put("level", address.getLevel());//等级，默认0表示非默认地址，1表示默认地址
            map.put("sex", address.getSex());
            map.put("lng", address.getLng());
            map.put("lat", address.getLat());
            map.put("status", address.getStatus());
            map.put("addressId", address.getId());
            map.put("contactsId", contacts.getId());
            map.put("areaCode", address.getAreaCode());
            contactMapList.add(map);
        }
        return JsonResp.ok(contactMapList);
    }



    /**
     * @获取通讯录详情-ByContactsId
     * @param contactsId
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/contactsDetails",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findContactsDetailsByContactsId(Long contactsId) {
        log.debug("获取通讯录详情-ByContactsId");
        return JsonResp.ok(contactsDao.findOne(contactsId));
    }

    /**
     * @根据电话查询用户信息
     * @param phone
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/findcontactsByPhone",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findContactsDetailsByContactsId(String phone) {
        log.debug("根据电话查询用户信息-");
        List<Map> userAddressList = new ArrayList<>();
        List<Contacts> contactsList = contactsDao.findByPhoneLike(phone);
        if (!contactsList.isEmpty() && contactsList != null) {
            for (int i = 0, y = contactsList.size(); i < y; i++) {
                Address address = contactsList.get(i).getAddress();//获取用户地址
                Map map = new HashMap<>();
                map.put("phone", phone);
                map.put("realName", address.getRealName());
                map.put("province", address.getProvince());
                map.put("city", address.getCity());
                map.put("county", address.getCounty());
                map.put("addressDetail", address.getAddressDetail());
                map.put("addRessId", address.getId());
                userAddressList.add(map);
            }
            return JsonResp.ok(userAddressList);
        } else {
            String str = "沒有查到用戶";
            return JsonResp.fa(str);
        }
    }


    /**
     * @搜索页面显示的数据
     *
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/findAddressList",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findAddressList(Long shopId) {
        log.debug("搜索页面显示的数据)");
//        JsonResp loginUser = userService.findLoginUser();
        User loginUser =userDao.findOne(shopId);
        List<Map> addressList=new ArrayList<>();
       List<Contacts> contactsList=contactsDao.findByShop(loginUser);
        for(int i=0,y=contactsList.size();i<y;i++){
            Address address=contactsList.get(i).getAddress();
            Map map =new HashMap();
            map.put("province",address.getProvince());
            map.put("city",address.getCity());
            map.put("county",address.getCounty());
            map.put("addressDetal",address.getAddressDetail());
            map.put("realName",address.getRealName());
            map.put("phone",address.getPhone());
            addressList.add(map);
        }


        return JsonResp.ok(addressList);
    }



    /**
     * @分页查询通讯录(jpa方式)
     * @param contacts 分页条件
     * @param pageNum 第几页
     * @param pageSize 每页的条数
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/jpa/page",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findPageContactsJpa(@RequestBody(required = false) Contacts contacts, Integer pageNum, Integer pageSize) {
        log.debug("分页查询通讯录(jpa方式)");
        //多条件排序Sort
        //Sort sort = new Sort(Sort.Direction.DESC, "createdate").and(new Sort(Sort.Direction.AES, "id"));
        //排序Sort
        Sort sort = new Sort(Sort.Direction.DESC, "gmtDatetime");
        Pageable pageable = new PageRequest(pageNum-1, pageSize, sort);
        Page page = null;
        if (null == contacts) {
            page = contactsDao.findAll(pageable); //无条件分页
        }else{
            final String condition =  contacts.getPhone();
            page = contactsDao.findAll( 		  //条件分页
                    (root, criteriaQuery, cb) -> {
                        Predicate predicate = cb.conjunction();
                        List<Expression<Boolean>> expressions = predicate.getExpressions();
                        if (StringUtils.isNotBlank(condition)) {
                            expressions.add(cb.like(root.<String>get("phone"), "%"+ condition +"%"));
                        }
                        return predicate;
                    }, pageable);
        }
//        List<Contacts> content = page.getContent();
//        for (Contacts contacts1 : content) {
//        }
        return JsonResp.ok(new PageDto(page));
    }

    /**
     * @分页查询通讯录(jpa方式后台用)
     * @param pageNum 第几页
     * @param pageSize 每页的条数
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/jpa/pageByHouTai",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findPageContactsJpaByHouTai( Integer pageNum, Integer pageSize,String search) {
        log.debug("分页查询通讯录(jpa方式后台用)");
        //多条件排序Sort
        //Sort sort = new Sort(Sort.Direction.DESC, "createdate").and(new Sort(Sort.Direction.AES, "id"));
        //排序Sort
        Sort sort = new Sort(Sort.Direction.DESC, "gmtDatetime");
        Pageable pageable = new PageRequest(pageNum-1, pageSize, sort);
        Page page = null;
        if (StringUtils.isEmpty(search)) {
            page = contactsDao.findAll(pageable); //无条件分页
        }else{
            page = contactsDao.findAll( 		  //条件分页
                    (root, criteriaQuery, cb) -> {
                        Predicate predicate = cb.conjunction();
                        List<Expression<Boolean>> expressions = predicate.getExpressions();
                        List<Address> addressList =addressDao.findByPhone(search);
                        List<Long> ids = addressList.stream().map(Address::getId).collect(Collectors.toList());
                        if(addressList!=null&&!addressList.isEmpty()){
                            CriteriaBuilder.In<Object> stick = cb.in(root.get("address"));
                            for (Long l : ids) {
                                expressions.add(stick.value(l));
                            }
                        }else{
                            CriteriaBuilder.In<Object> stick = cb.in(root.get("address"));
                            expressions.add(stick.value(0));
                        }
                        return predicate;
                    }, pageable);
        }
        return JsonResp.ok(new PageDto(page));
    }

    /**
     * @删除通讯录-one(永久)
     * @param contactsId
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/deleteContactsOne",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp deleteContactsOne(Long contactsId) {
        log.debug("删除通讯录-one(永久)");
        contactsDao.delete(contactsId);
        return JsonResp.ok();
    }





    /**
     * @根据通讯录id删除一条通讯录
     * @param contactsId
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/deleteContactsById",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp deleteContactsById(Long contactsId) {
        log.debug("根据通讯录id删除一条通讯录)");
         contactsDao.delete(contactsId);
        return JsonResp.ok();
    }







    /**
     * @批量删除通讯录(永久)
     * @param contactss
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/deleteSomeContacts",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp deleteSomeContacts(@RequestBody List<Contacts> contactss) {
        log.debug("批量删除通讯录(永久)");
        contactsDao.delete(contactss);
        return JsonResp.ok();
    }

    /**
     * @分页查询单个用户通讯录(jpa方式)
     * @param userId 分页条件
     * @param pageNum 第几页
     * @param pageSize 每页的条数
     * @return 返回值JsonResp
     */
    @RequestMapping(value = "/jpa/pageByUser",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
    public JsonResp findPageContactsJpaByUser(Long userId, Integer pageNum, Integer pageSize) {
        log.debug("分页查询单个用户通讯录(jpa方式)");
        //多条件排序Sort
        //Sort sort = new Sort(Sort.Direction.DESC, "createdate").and(new Sort(Sort.Direction.AES, "id"));
        //排序Sort
        Sort sort = new Sort(Sort.Direction.DESC, "gmtDatetime");
        Pageable pageable = new PageRequest(pageNum-1, pageSize, sort);
        Page page = null;
        if (null == userId) {
        }else{
            page = contactsDao.findAll( 		  //条件分页
                    (root, criteriaQuery, cb) -> {
                        Predicate predicate = cb.conjunction();
                        List<Expression<Boolean>> expressions = predicate.getExpressions();
                        User user = userDao.findOne(userId);
                        if(user!=null) {
                            expressions.add(cb.equal(root.get("shop"), user));
                        }
                        return predicate;
                    }, pageable);
        }
        return JsonResp.ok(new PageDto(page));
    }

}
